package pac1_rgr;

import process.Actor;
import process.DispatcherFinishException;
import process.IWaitCondition;
import queues.QueueForTransactions;
import queues.Store;
import widgets.ChooseRandom;

public class Car extends Actor {

	private QueueForTransactions queueOfCars;
	private int sizeOfCar;
	private Main gui;
	private Model model;
	private ChooseRandom rnd;
	private QueueForTransactions queuePlatform;
	private QueueForTransactions queueOfContainers;
	private double wait_time;

	public Car(String name, Main gui, Model model) {
		this.setNameForProtocol(name);
		this.model = model;
		this.queueOfCars = model.getQueueOfCars();
		this.queuePlatform = model.getQueuePlatform();
		this.sizeOfCar = gui.getChooseDataCarSize().getInt();
		this.rnd = gui.getChooseRandomWay();
		this.gui = gui;
		this.queueOfContainers = getQueueOfContainers();

	}

	public void addContainer(Object o) {
		this.queueOfContainers.addLast(o);
	}

	@Override
	protected void rule() {
		IWaitCondition morning = new IWaitCondition() {

			@Override
			public boolean testCondition() {
				return getDispatcher().getCurrentTime() % 24 == 8;
			}

			public String toString() {
				return "8 ранку";
			}
		};
		IWaitCondition evening = new IWaitCondition() {

			@Override
			public boolean testCondition() {
				return getDispatcher().getCurrentTime() % 24 == 17;
			}

			public String toString() {
				return "5 вечора";
			}
		};
		IWaitCondition full = new IWaitCondition() {

			@Override
			public boolean testCondition() {
				return queueOfContainers.queue.size() == sizeOfCar;
			}

			public String toString() {
				return "завантаження";
			}
		};

		try {
			waitForCondition(morning);
		} catch (DispatcherFinishException e) {
			return;
		}

		while (true) {
			if (getDispatcher().getCurrentTime() >= gui
					.getChooseDataModelTime().getDouble()) {
				return;
			}

			wait_time = rnd.next();
			double t = wait_time + getDispatcher().getCurrentTime();
			if (t % 24 >= 17) {
				try {
					waitForCondition(morning);
				} catch (DispatcherFinishException e) {
					return;
				}
				getDispatcher()
						.printToProtocol(
								this.getNameForProtocol()
										+ " чекае ранку, бо не встигне заватажитись до вечора");
			}
			getDispatcher().printToProtocol(
					this.getNameForProtocol() + " поїхав на завантаження");
			holdForTime(wait_time);
			queueOfCars.addLast(this);
			try {
				waitForCondition(full);
			} catch (DispatcherFinishException e) {
				return;
			}
			queueOfCars.remove(this);
			wait_time = rnd.next();
			t = wait_time + getDispatcher().getCurrentTime();
			if (t % 24 >= 17) {
				try {
					getDispatcher().printToProtocol(
							this.getNameForProtocol()
									+ " не встигне повернутися до вечора");
					waitForCondition(morning);
				} catch (DispatcherFinishException e) {
					return;
				}
				getDispatcher().printToProtocol(
						this.getNameForProtocol() + " поїхав на розвантаження");
				holdForTime(wait_time);

			}
			for (int i = 0; i < queueOfContainers.queue.size(); i++) {
				double tt = (Double) (queueOfContainers.removeFirst());
				double ct = getDispatcher().getCurrentTime() - tt;
				gui.getHisto1().add(ct);
				
			}
			getDispatcher().printToProtocol(
					this.getNameForProtocol() + " розвантажився");
		}

	}

	public boolean isFull() {
		return queueOfContainers.queue.size() == sizeOfCar;
	}

	public QueueForTransactions getQueueOfContainers() {
		if (queueOfContainers == null) {
			queueOfContainers = new QueueForTransactions();
			queueOfContainers.setNameForProtocol("Черга контейнерiв у "
					+ this.getNameForProtocol());
			queueOfContainers.setDispatcher(model.getDispatcher());
		}
		return queueOfContainers;
	}
}
